<template>
    <!-- 提示框 -->
    <!-- attrs绑定tooltip原有属性 -->
    <el-tooltip
        :disabled="isShowTooltip"
        :placement="placement"
        :show-after="showAfter"
        :popper-class="popperClass"
        v-bind="$attrs">
        <!-- tooltip slot文本 -->
        <template v-slot:content>
            <!-- todo:后期可以扩展自定义slot -->
            <p :class="slotClass" :style="{ 'max-width': tipMaxWidth, margin: 0, ...slotStyle }">
                <slot name="content">
                    {{ content }}
                </slot>
            </p>
        </template>
        <!-- 显示图标 -->
        <img
            class="custom-tooltip-icon"
            v-if="type === 'icon'"
            :src="iconSrc"
            :class="iconClass"
            :style="iconStyle"
            alt="" />
        <!-- 显示文本 -->
        <p
            v-else
            class="text-ellipsis-container"
            :class="className"
            :style="style"
            @mouseover.self="onMouseOver($event)">
            {{ content || '--' }}
        </p>
    </el-tooltip>
</template>

<script setup>
import { ref } from 'vue';

// todo:后期还可以自定义显示框文本slot
// todo:prop后期扩展可以传入和tooltip所有支持的属性，v-bind="$attrs"
// todo:ref 页面中只存在一个tooltip避免过度渲染

const props = defineProps({
    // 提示框类型
    type: {
        type: [String],
        default: 'text'
    },
    // 提示框文本内容
    content: {
        type: [String, Number],
        default: '--'
    },
    // 提示框位置
    placement: {
        type: [String],
        default: 'top'
    },
    // 提示框延迟多久显示
    showAfter: {
        type: [Number],
        default: 800
    },
    // 提示框自定义class
    popperClass: {
        type: [String],
        default: 'text-ellipsis-tooltip'
    },
    // 是否根据容器宽度定义tooltip最大宽度，关闭后只读取tooltipMaxWidth设置的宽度
    tipWidthForParent: {
        type: [Boolean],
        default: true
    },
    // 提示框最大宽度,todo自适应宽度
    tooltipMaxWidth: {
        type: [String, Number],
        default: '300'
    },
    // todo:自定义提示框slot样式
    slotStyle: {
        type: [Object],
        default: () => {
            // return {
            //     fontSize: '12px',
            //     fontWeight: 400,
            // };
        }
    },
    slotClass: {
        type: [String],
        default: 'text-ellipsis-tooltip-slot'
    },
    // 自定义显示文本class
    className: {
        type: [String],
        default: ''
    },
    // 显示文本超过几行隐藏
    line: {
        type: [Number],
        default: 1
    },
    // 显示文本样式
    style: {
        type: [Object],
        default: () => {
            // return {
            //     fontSize: '14px',
            //     fontWeight: 400,
            //     color: '#33302d'
            // };
        }
    },
    /** 图标相关配置start **/
    // 图标地址
    iconSrc: {
        type: [String],
        default: 'https://img.static-keyid.cn/toolspace/scrm/2023/10/1698389457695nyqh95u6g0yqv7br.png'
    },
    // 图标自定义class
    iconClass: {
        type: [String],
        default: ''
    },
    // 图标自定义样式
    iconStyle: {
        type: [Object],
        default: () => {}
    }
    /** 图标相关配置end **/
});

let isShowTooltip = ref(false); // 是否展示提示框
let tipMaxWidth = ref(`${props.tooltipMaxWidth}px`); // 提示框最大宽度
/* 鼠标移入文本，控制提示框 */
const onMouseOver = (e, ref) => {
    try {
        /* 获取当前承载文本的容器元素 */
        const target = e.target;

        /* currentWidth 为文本在页面中所占的宽度，创建标签，加入到页面，获取currentWidth ,最后在移除*/
        let tempTag = document.createElement('span');
        /* ！！！把内容塞进临时tag需要指定字号，这样宽度才能准确，获取的是显示文本的字号大小 */
        tempTag.style.fontSize = window.getComputedStyle(target).fontSize; // 获取文本容器字号大小
        tempTag.innerText = props.content; // 临时标签插入文本内容
        tempTag.className = 'getTextWidth'; // 设置临时标签class
        document.querySelector('body').appendChild(tempTag); // 页面插入临时标签
        let currentWidth = document.querySelector('.getTextWidth').offsetWidth; // 获取文本总宽度
        document.querySelector('.getTextWidth').remove(); // 移除临时标签

        /* cellWidth为显示文本容器的最大宽度 */
        const cellWidth = target.offsetWidth;

        /* 当文本总宽度小于||等于容器宽度N倍时(N=行数line)，判断文本是否超过文本容器设置的{line}行 */
        isShowTooltip.value = !!(currentWidth <= props.line * cellWidth);
        // todo:是否根据容器宽度决定
        // 提示框宽度根据文本内容容器决定，如果大于tooltipMaxWidth就取容器宽度，否则取tooltipMaxWidth
        tipMaxWidth.value =
            (props.tipWidthForParent && cellWidth > props.tooltipMaxWidth ? cellWidth : props.tooltipMaxWidth) + 'px';
    } catch {
        // 如果无法正常获得宽度，则直接打开提示框
        isShowTooltip.value = true;
    }
};
</script>

<style lang="scss" scoped>
.text-ellipsis-container {
    word-break: break-all;
    text-overflow: ellipsis;
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: v-bind(line); /* 这里是超出几行省略 */
    overflow: hidden;
    margin: 0;
}
.custom-tooltip-icon {
    display: inline-block;
    width: 16px;
    height: 16px;
    cursor: pointer;
    margin-left: 4px;
}
</style>
